import datetime
import logging
import string

import webapp2
from google.appengine.api import users, blobstore
from google.appengine.ext.webapp import blobstore_handlers
from util.webapp import ShopkeepApplication, ShopkeepHandler
from util.uri import Uri
from .search import SearchPage
from models.Item import Item, STATUS_ACTIVE, STATUS_INACTIVE
from models.User import User

class ItemPage(ShopkeepHandler):
	def get(self):
		action = self.request.GET.get('action', 'view')
		user = users.get_current_user()
		if self.item and not self.item.canView(user):
			self.abort(403)

		data = {
			'user': user,
			'item': self.item,
			'token': self.token,
		}

		if action == 'view':
			self.render_response('item_view.html', data)
		elif action == 'edit':
			if self.item and not self.item.canEdit(user):
				self.abort(403)
			self.render_response('item_edit.html', data)
		elif action == 'upload':
			if self.item and not self.item.canEdit(user):
				self.abort(403)
			data['upload_url_photo'] = blobstore.create_upload_url(repr(Uri(self.request.url).relPath('photo')))
			data['upload_url_video'] = blobstore.create_upload_url(repr(Uri(self.request.url).relPath('video')))
			self.render_response('item_upload.html', data)
		else:
			self.abort(400)

	def post(self):
		user = users.get_current_user()
		action = self.request.POST.get('action', 'edit')
		if self.item and not self.item.canEdit(user):
			self.abort(403)

		if action == 'deactivate':
			self.item.status = STATUS_INACTIVE
			self.item.put()
			logging.info("Deactivated", extra={'target': self.item})
			self.get()
		elif action == 'activate':
			self.item.status = STATUS_ACTIVE
			self.item.put()
			logging.info("Activated", extra={'target': self.item})
			self.get()
		elif action == 'delete':
			self.delete()
			self.redirect(self.request.url + '/..')
		else:
			self.put(self.request.POST)
			self.redirect(self.request.host_url + '/users/' + str(User.getUser(user).key().id()) + '/items/' + str(self.item.key().id()))

	def put(self, data=None):
		user = users.get_current_user()
		if self.item and not self.item.canEdit(user):
			self.abort(403)

		if data is None:
			data = urlparse.parse_qs(
				self.request.body,
				keep_blank_values=True,
				strict_parsing=True
			)
			assert 'title' in data
			assert 'desc' in data
			assert 'price' in data
			assert 'viewers' in data

		if 'title' in data:
			self.item.title = data['title']
		if 'desc' in data:
			self.item.desc = data['desc']
		if 'price' in data:
			try:
				price = float(data['price'])
			except ValueError:
				self.abort(400)
			self.item.price = price
		if 'viewers' in data:
			if isinstance(data['viewers'], list):
				viewers = data['viewers']
			else:
				viewers = filter(None, map(string.strip, data['viewers'].split("\n")))

			viewer_users = []
			for viewer in viewers:
				try:
					user = users.User(viewer)
				except users.UserNotFoundError:
					self.abort(400)
				else:
					viewer_users.append(user)
			self.item.viewers = viewer_users

		self.item.put()
		logging.info("Item created/edited", extra={'target': self.item})

	def delete(self):
		user = users.get_current_user()
		if self.item and not self.item.canEdit(user):
			self.abort(403)

		logging.info("Deleted", extra={'target': self.item})
		self.item.delete()
	
	@webapp2.cached_property
	def item(self):
		info = self.request.path.split('/')

		item = None
		if info[4] == 'new':
			item = Item(
				title=self.request.get('title', 'Title'),
				expiry_time=datetime.datetime.utcnow() + datetime.timedelta(days=30),
				price=float(self.request.get('price', 0))
			)
		else:
			try:
				user_id, item_id = int(info[2]), int(info[4])
			except ValueError:
				self.abort(400)

			item = Item.get_by_id(item_id)

		if item is None:
			self.abort(404)
			# Should not be reached, since self.abort throws excpt

		return item

class PhotoUpload(blobstore_handlers.BlobstoreUploadHandler, ItemPage):
	def post(self):
		photo = self.get_uploads('file')
		blob_info = photo[0]
		self.item.photo = blob_info.key()
		self.item.put()

		user = User.getUser(self.item.seller)
		self.redirect('/users/{0}/items/{1}'.format(user.key().id(), self.item.key().id()))

class VideoUpload(blobstore_handlers.BlobstoreUploadHandler, ItemPage):
	def post(self):
		video = self.get_uploads('file')
		blob_info = video[0]
		self.item.video = blob_info.key()
		self.item.put()

		user = User.getUser(self.item.seller)
		self.redirect('/users/{0}/items/{1}'.format(user.key().id(), self.item.key().id()))

app = ShopkeepApplication([
	('/users/.+/items/.+/photo', PhotoUpload),
	('/users/.+/items/.+/video', VideoUpload),
	('/users/.+/items/.+', ItemPage),
	webapp2.Route('/users/.+/items', ItemPage, methods=['POST']),
	('/users/.+/items', SearchPage)
])
